package com.jsz.peini.common.bean;

import java.util.List;

import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jsz.peini.common.constants.Constants;

/**
 * @Title: ResultMessage.java
 * @Description: 
 * @author: gaochong
 * @date: 2016年12月14日 下午3:52:57
 * @version: V1.0
 */
public class ResultMessage {

    /**
     * 返回代码
     */
    private long    code;

    /**
     * 操作提示信息
     */
    private String message;

    /**
     * 操作数据
     */
    private Object data;
    
    /**
     * error code 1-30用于公共错误
     */
    private static final int commonCodeNum = 30;
    
    private ResultMessage(){
        
    }

    private ResultMessage(int code, String message) {
        this.code = code;
        this.message = message;
    }
    
    public static ResultMessage newInstance(){
        return new ResultMessage().internalSetCode(0);
    }

    public long getCode() {
        return code;
    }

    private ResultMessage internalSetCode(long code) {
        this.code = code;
        return this;
    }
    
    public ResultMessage setCode(long code) {
        if(code < commonCodeNum){
            throw new RuntimeException("Error code not available, the code can't less than " + commonCodeNum);
        }
        return this.internalSetCode(code);
    } 

    public String getMessage() {
        return message;
    }

    public ResultMessage setMessage(String message) {
        this.message = message;
        return this;
    }

    public Object getData() {
        return data;
    }

    public ResultMessage setData(Object data) {
        this.data = data;
        return this;
    }
    
    private static final SerializerFeature[] serializerFeatures = new SerializerFeature[]{SerializerFeature.PrettyFormat,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullListAsEmpty,
    	SerializerFeature.WriteNullStringAsEmpty,SerializerFeature.WriteNullNumberAsZero,SerializerFeature.WriteNullBooleanAsFalse,SerializerFeature.DisableCircularReferenceDetect};
    
    /**
     * 只返回想要的field
     */
    public ResultMessage setData(Object data, String... fields) {
    	if(List.class.isInstance(data)){
    		JSONArray array = (JSONArray)JSON.parse(JSON.toJSONStringWithDateFormat(data, "yyyy-MM-dd HH:mm:ss",serializerFeatures));
    		JSONArray newArray = new JSONArray();
        	for(Object json : array){
        		JSONObject newJson = filterFields((JSONObject)json, fields);
        		newArray.add(newJson);
        	}
            this.data = newArray;
    	}else{
    		JSONObject json = (JSONObject)JSON.parse(JSON.toJSONStringWithDateFormat(data, "yyyy-MM-dd HH:mm:ss",serializerFeatures));
    		JSONObject newJson = filterFields(json, fields);
            this.data = newJson;
    	}
        return this;
    }
    
    private JSONObject filterFields(JSONObject json, String... fields){
		JSONObject newJson = new JSONObject();
    	for(String field : fields){
    		if(field.indexOf('.') < 0){
    			Object value = json.get(field);
    			newJson.put(field, value == null ? "" : value);
    		}else{
    			Object value = JSONPath.eval(json, field);
    			JSONPath.set(newJson, field, value == null ? "" : value);
    		}
    	}
        return newJson;
    }
    
    public static ResultMessage SUCCESS = new ResultMessage().internalSetCode(Constants.SUCCESS)
            .setMessage("成功.");
    public static ResultMessage FAIL = new ResultMessage().internalSetCode(Constants.FAIL)
            .setMessage("访问失败!");
    public static ResultMessage SIGN_ERROR = new ResultMessage().internalSetCode(Constants.FAIL)
            .setMessage("签名错误!");
    public static ResultMessage AUTH_FAILED = new ResultMessage().internalSetCode(Constants.INVALID)
            .setMessage("身份失效!");

    @Override
    public String toString() {
        return JSONObject.toJSONString(this);
    }
    
    public ResultMessage setBindingResult(BindingResult binding){
    	StringBuffer buff = new StringBuffer(200);
    	for(ObjectError err: binding.getAllErrors()){
    		if(FieldError.class.isInstance(err)){
    			buff.append(((FieldError)err).getField()).append(":").append(err.getDefaultMessage()).append("; ");
    		}else{
    			buff.append(err.getObjectName()).append(":").append(err.getDefaultMessage()).append("; ");
    		}
    	}
    	this.setMessage(buff.toString());
    	return this;
    }
    

}
